package com.chlitina.store.modules.cash.model;

import java.util.ArrayList;
import java.util.List;

import com.chlitina.store.modules.cash.entity.StoreCardAll;
import com.chlitina.store.modules.cash.entity.StoreCardDuration;
import com.chlitina.store.modules.cash.entity.StoreCardProduct;
import com.chlitina.store.modules.cash.entity.StoreCardTimes;
import com.chlitina.store.modules.cash.service.PaymentUility;
import com.chlitina.store.modules.employee.entity.Employee;

/**
 * All the time, total should not be changed only when adding or remove new
 * card.<br>
 * cashMoney is the payment by cash.<br>
 * leftToPay is left to pay by cash or cards<br>
 * cardsPayment is payment by cards.<br>
 * That is <code>total = left+cashMoney+cardsPayment.money</code>
 * 
 * @author Songsong.xu
 * 
 */
public class NewCardsPayment {
	NewCards newcards;

	public NewCardsPayment(NewCards newcards) {
		this.newcards = newcards;
	}

	private Employee employee;

	private List<AllCardPaymentDetail> cardsPaymentDetails = new ArrayList<AllCardPaymentDetail>();
	private float totalRealCost;
	private float totalRequiredCost;

	private float totalRealCostForTimes;
	private float totalRequiredCostForTimes;

	private float totalRealCostForProduct;
	private float totalRequiredCostForProduct;

	private float totalRealCostForDuration;
	private float totalRequiredCostForDuration;

	private float totalRealCostForAll;
	private float totalRequiredCostForAll;

	private float totalCashCost;

	public float getTotalRealCost() {
		return totalRealCost;
	}

	public float getTotalRequiredCost() {
		return totalRequiredCost;
	}

	public float getTotalRealCostForTimes() {
		return totalRealCostForTimes;
	}

	public float getTotalRequiredCostForTimes() {
		return totalRequiredCostForTimes;
	}

	public float getTotalRealCostForProduct() {
		return totalRealCostForProduct;
	}

	public float getTotalRequiredCostForProduct() {
		return totalRequiredCostForProduct;
	}

	public float getTotalRealCostForDuration() {
		return totalRealCostForDuration;
	}

	public float getTotalRequiredCostForDuration() {
		return totalRequiredCostForDuration;
	}

	public float getTotalRealCostForAll() {
		return totalRealCostForAll;
	}

	public float getTotalRequiredCostForAll() {
		return totalRequiredCostForAll;
	}

	public float getTotalCashCost() {
		return totalCashCost;
	}

	private void reset() {
		for (AllCardPaymentDetail payment : cardsPaymentDetails) {
			payment.reset();
		}
		totalRealCost = 0;
		totalRequiredCost = 0;
		totalCashCost = 0;

		totalRealCostForTimes = 0;
		totalRequiredCostForTimes = 0;

		totalRealCostForProduct = 0;
		totalRequiredCostForProduct = 0;

		totalRealCostForDuration = 0;
		totalRequiredCostForDuration = 0;

		totalRealCostForAll = 0;
		totalRequiredCostForAll = 0;
	}

	public void calculatePayment(Member member) {
		reset();
		for (CardCart cart : newcards.getAllCards()) {
			StoreCardAll card = (StoreCardAll) cart.getCard();
			totalRequiredCostForAll += card.getTemplate().getRetail_price();
			totalRealCostForAll +=cart.getReal_cost();
			payForNewcard(member, cart.getReal_cost());
		}
		for (CardCart cart : newcards.getDurationCards()) {
			StoreCardDuration card = (StoreCardDuration) cart.getCard();
			totalRequiredCostForDuration += card.getTemplate()
					.getRetail_price();
			totalRealCostForDuration += cart.getReal_cost();
			payForNewcard(member, cart.getReal_cost());
		}

		for (CardCart cart : newcards.getProductCards()) {
			StoreCardProduct card = (StoreCardProduct) cart.getCard();
			totalRequiredCostForProduct += card.getTemplate().getRetail_price();
			totalRealCostForProduct +=cart.getReal_cost();
			payForNewcard(member, cart.getReal_cost());
		}

		for (CardCart cart : newcards.getTimesCards()) {
			StoreCardTimes card = (StoreCardTimes) cart.getCard();
			totalRequiredCostForTimes += card.getTemplate().getRetail_price();
			totalRealCostForTimes += cart.getReal_cost();
			payForNewcard(member, cart.getReal_cost());
		}

		totalRealCost = totalRealCostForTimes + totalRealCostForDuration
				+ totalRealCostForProduct + totalRealCostForAll;
		totalRequiredCost = totalRequiredCostForTimes
				+ totalRequiredCostForDuration + totalRequiredCostForProduct
				+ totalRequiredCostForAll;
	}

	private void payForNewcard(Member member, float real_cost) {
		AllCardPayment allcard = PaymentUility
				.findBestAllCardPaymentForNewcard(member.getAvaibleAllCards(),
						real_cost);
		if (allcard == null) {
			totalCashCost += real_cost;
		} else {
			AllCardPaymentDetail detail = PaymentUility.findCardAllPaymentDetailByPaymentId(getCardsPaymentDetails(), allcard.getPaymentId());
			if (detail == null) {
				detail = new AllCardPaymentDetail();
				detail.setCardPayment(allcard);
				detail.setCurrentLeftMoney(allcard.getCurrentMoney());
				detail.appendPay(real_cost);
				getCardsPaymentDetails().add(detail);
			} else {// 已经使用过的卡，进行累计计算
				detail.appendPay(real_cost);
			}
			member.updateAvailableAllCards();
		}
	}

	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	public List<AllCardPaymentDetail> getCardsPaymentDetails() {
		return cardsPaymentDetails;
	}

	public void setCardsPaymentDetails(
			List<AllCardPaymentDetail> cardsPaymentDetails) {
		this.cardsPaymentDetails = cardsPaymentDetails;
	}
}
